/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.gbvbahia.projeto.beans.facade;

import br.com.gbvbahia.projeto.beans.facade.commons.AbstractEntityBeans;
import br.com.gbvbahia.projeto.beans.facade.interfaces.UsuarioFacade;
import br.com.gbvbahia.projeto.entidades.Usuario;
import br.com.gbvbahia.projeto.exceptions.EntityException;
import br.com.gbvbahia.utils.Base64Encoder;
import br.com.gbvbahia.utils.StringBeanUtils;
import br.com.gbvbahia.utils.UtilBeans;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @since 17/04/2012
 * @author Guilherme Braga
 */
@Repository(value = "usuarioFacade")
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public class UsuarioBean extends AbstractEntityBeans<Usuario, String>
        implements UsuarioFacade {

    /**
     * Unidade de persistência <i>jdbc/***</i>. <br>EXTENDED: O
     * contexo de persistencia extendido vive por mais tempo que uma
     * transação, as instâncias de um objeto de entidade que são
     * acopladas a uma contexto estendido permanecem gerenciadas mesmo
     * depois de uma transação ser concluída. <br>TRANSACTION: O
     * contexto de persistência duram pelo tempo de uma transação e
     * são fechados quando uma transação se completa. <b>Somente
     * instâncias EntityManager injetadas com a anotação
     * @PersistenceContext podem ter escopo de trasação.</b>
     * <br>Explicação retirada do livro Enterprise JavaBeans 3.0
     * O'Reilly. Esta parte de o EntityManager somente em casos que o
     * mesmo é injetado, você pode se perguntar, como eu, no Spring o
     * EntityManager também é injetado, acredito que o autor não
     * lembrou do Spring quando escreveu isso, na época o Spring tava
     * iniciando a injeção, a 1ª edição é de 2006.
     */
    @PersistenceContext(unitName = UtilBeans.PERSISTENCE_UNIT,
    type = PersistenceContextType.EXTENDED)
    private EntityManager dao;

    /**
     * Construtor padrão que passa a classe que representa para
     * AbstractEntityBeans.
     */
    public UsuarioBean() {
        super(Usuario.class);
    }

    @Override
    protected EntityManager getEntityManager() {
        return dao;
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public List<Usuario> buscarUsuarioPorNomeLogin(final String nome,
            final String login, final int[] range) {
        Map<String, Object> parans = AbstractEntityBeans.getMapParans();
        parans.put("firstName", acertaNomeMeio(nome));
        parans.put("userId", acertaNomeMeio(login));
        return listPesqParam("Usuario.findByNameOrLoginOrAll",
                parans, range[1] - range[0], range[0]);
    }

    @Override
    @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
    public Integer contarPorNome(final String nome, final String login) {
        Map<String, Object> parans = AbstractEntityBeans.getMapParans();
        parans.put("firstName", acertaNomeMeio(nome));
        parans.put("userId", acertaNomeMeio(login));
        return this.pesqCount("Usuario.countByNameOrLoginOrAll",
                parans).intValue();
    }

    @Override
    public void alterarSenha(final Usuario usuario,
            final String novaSenha) throws EntityException {
        usuario.setPass(Base64Encoder.encryptPassword(novaSenha));
        super.update(usuario);
    }

    @Override
    public void create(final Usuario entity) throws EntityException {
        try {
            entity.setPass(Base64Encoder.encryptPassword(entity.getPass()));
        } catch (IllegalArgumentException ex) {
            throw new EntityException("PasswordNull");
        }
        super.create(entity);
    }

    @Override
    public void update(final Usuario entity) throws EntityException {
        try {
            entity.setPass(Base64Encoder.encryptPassword(entity.getPass()));
        } catch (IllegalArgumentException ex) {
            throw new EntityException("PasswordNull");
        }
        super.update(entity);
    }

    /**
     * Insere % no inicio e final, mas se for null ou vazio faz
     * tratamento para buscar todos na consulta.
     *
     * @param nome java.lang.String com o valor a ser buscado, pode
     * ser null ou vazio.
     * @return java.lang.String tratada para SQL like.
     */
    private String acertaNomeMeio(final String nome) {
        return StringBeanUtils.acertaNomeParaLike(nome,
                StringBeanUtils.LIKE_MIDDLE);
    }
}
